using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System.Threading.Tasks;
using Soft2ApiDemo.Infrastructure.Parameter;
using Soft2ApiDemo.Infrastructure.Dto;

namespace Soft2ApiDemo.Infrastructure.Utils
{
    public static class TokenHelper
    {
        public static string GenerateToken(TokenParameter tokenParameter)
        {
            var claims = new[]
             {
                new Claim("Name", "admin"),
                new Claim("Role", "admin"),
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenParameter.Secret));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var jwtToken = new JwtSecurityToken(tokenParameter.Issuer, null, claims, expires: DateTime.UtcNow.AddMinutes(tokenParameter.AccessExpiration), signingCredentials: credentials);

            var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);

            return token;
        }

        public static RefreshTokenDto RefreshToken(TokenParameter tokenParameter, string oldToken)
        {
            // 这里是刷新token的用法，没有数据验证、没有用户标识，也没有经过完美的测试，请勿直接用于生产环境，否则，后果自负

            //这儿是验证Token的代码
            var handler = new JwtSecurityTokenHandler();
            ClaimsPrincipal claim = handler.ValidateToken(oldToken, new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenParameter.Secret)),
                ValidateIssuer = false,
                ValidateAudience = false,
                ValidateLifetime = false,
            }, out SecurityToken securityToken);
            var username = claim.Identity.Name;
            //这儿是生成Token的代码
            var token = GenerateToken(tokenParameter);
            //此处的RefreshToken是直接指定和字符串，在正式项目中，应该是一个可验证的加密串，如md5、hash等
            var refreshToken = "654321";

            var res = new RefreshTokenDto
            {
                AccessToken = token,
                RefreshToken = refreshToken
            };
            return res;
        }
    }
}